/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package aiaudio.database.tables;

import aiaudio.database.Family;
import java.io.IOException;
import java.util.Map;
import java.util.NavigableMap;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;

/**
 *
 * @author nastya
 */
public class RatingsMatrixTable extends TableStructure {

    private static final Family STATISTICS = new Family("s");
    protected static final Family DATA = new Family("d");
    private static final Family RATINGS = new Family("r");

    public static void addUserRating(Put put, byte[] user, double rating) {
        put.add(RATINGS.getNameAsBytes(), user, UNMODIFIABLE_TIMESTAMP, Bytes.toBytes(rating));
    }

    public static double getArtistRatingOrDefault(Result artistRatingList, Result defaultUsersRatingsList, byte[] user) {
        byte[] res = artistRatingList.getValue(RATINGS.getNameAsBytes(), user);
        if (res == null) {
            return Bytes.toDouble(defaultUsersRatingsList.getValue(RATINGS.getNameAsBytes(), user));
        }
        return Bytes.toDouble(res);

    }

    public static double getValue(Result defaultVoting, byte[] user) {
        byte[] value = defaultVoting.getValue(RATINGS.getNameAsBytes(), user);
        return Bytes.toDouble(value);
    }

    public static double getRatingByArtist(Result res, String get) {
        return Bytes.toDouble(getRatingByArtistAsBytes(res, get));
    }

    public static byte[] getRatingByArtistAsBytes(Result res, String get) {
        return res.getValue(RATINGS.getNameAsBytes(), Bytes.toBytes(get));
    }

    public static void addDefaultRating(Put put, double rating) {
        addUserRating(put, ConstantRows.DefaultVoting.getNameAsBytes(), rating);
    }

    public static boolean isDefaultValue(String userName) {
        return userName.equals(ConstantRows.DefaultVoting.getName());
    }

    public static Result getDefaultRatings(HTable table) throws IOException {
        Get get = new Get(ConstantRows.DefaultVoting.getNameAsBytes());
        return table.get(get);
    }

    public static boolean isDefaultValue(byte[] artistId) {
        return isDefaultValue(Bytes.toString(artistId));
    }

    public static void copyDefaultValues(HTable fromTable, HTable toTable) throws IOException {
        byte[] rowKey = ConstantRows.DefaultVoting.getNameAsBytes();

        Get get = new Get(rowKey);
        Result result = fromTable.get(get);
        Put put = new Put(rowKey);
        for (KeyValue keyValue : result.list()) {
            put.add(keyValue.clone());
        }
        toTable.put(put);

    }

    @Override
    public Family[] getAllFamilies() {
        return new Family[]{STATISTICS, DATA, RATINGS};
    }

    public static NavigableMap<byte[], byte[]> getUsers(Result result) {
        return result.getFamilyMap(RATINGS.getNameAsBytes());
    }

    public static String getTypedKey(Map.Entry<byte[], byte[]> entry) {
        return Bytes.toString(entry.getKey());
    }

    public static double getTypedValue(Map.Entry<byte[], byte[]> entry) {
        return Bytes.toDouble(entry.getKey());
    }

    public static boolean existsInDataSet(HTable dataSet, byte[] user, byte[] artist) throws IOException {
        return getFromDataSet(dataSet, user, artist) != null;
    }

    public static byte[] getFromDataSet(HTable dataSet, byte[] user, byte[] artist) throws IOException {
        Get get = new Get(artist);
        Result result = dataSet.get(get);
        return result.getValue(RatingsMatrixTable.RATINGS.getNameAsBytes(), user);
    }

    public Result getDefaultValues(HTable tableInstance) throws IOException {
        Get get = new Get(ConstantRows.DefaultVoting.getNameAsBytes());
        Result result = tableInstance.get(get);
        return result;
    }
}
